const path = require("path"); // nodejs核心模块，专门用来处理路径问题
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
// nodejs核心模块，直接使用
const os = require("os");
// cpu核数
const threads = os.cpus().length;

module.exports = {
    // 入口
    entry: "./src/main.js",  // 相对路径
    // 输出
    output: {
        // 文件的输出路径
        // 开发模式不需要输出
        path: undefined,
        // 文件的输出名称
        // filename: "static/js/main.js",
        filename: "static/js/[name].js",
        // 给打包输出的其他文件命名
        chunkFilename: "static/js/[name].chunk.js",
        // 图片、字体等通过 type: 'asset' 处理的资源命名方式
        assetModuleFilename: "static/media/[hash:10][ext][query]",
    },
    // 加载器
    module: {
        rules: [
            // loader的配置
            {
                // 只能匹配上一个 loader, 剩下的就不匹配了。
                oneOf: [
                    {
                        // 用来匹配 .css 结尾的文件
                        // 记录问题：一定要使用/\.css$/进行匹配，否则只用/.css$/匹配会与 .scss发生冲突，导致出错，因为 .scss也包含了 .css这几个字符
                        // 将 .css 文件的测试规则修改为 /\.css$/，即添加了反斜杠来转义点号，这样就可以确保只匹配到以 .css 结尾的文件，而不是包含 .css 的任意文件名。
                        test: /\.css$/,
                        // use 数组里面 Loader 执行顺序是从右到左
                        use: ["style-loader", "css-loader"],
                    },
                    {
                        test: /\.less$/,
                        use: ["style-loader", "css-loader", "less-loader"],
                    },
                    {
                        // test: /.s[ac]ss$/,
                        test: /\.s[ac]ss$/i,// 匹配sass和scss
                        use: ["style-loader", "css-loader", "sass-loader"],
                    },
                    {
                        test: /\.styl$/,
                        use: ["style-loader", "css-loader", "stylus-loader"],
                    },
                    // 处理图片资源配置
                    {
                        test: /\.(png|jpe?g|gif|webp)$/,
                        type: "asset",
                        parser: {
                            dataUrlCondition: {
                                // 小于10kb的图片会被base64处理
                                // 优点：减少请求数量
                                // 缺点：体积变得更大
                                maxSize: 10 * 1024
                            }
                        },
                        // generator: {
                        //     // 将图片文件输出到 static/imgs 目录中
                        //     // 将图片文件命名 [hash:8][ext][query]
                        //     // [hash:8]: hash值取8位
                        //     // [ext]: 使用之前的文件扩展名
                        //     // [query]: 添加之前的query参数
                        //     filename: "static/imgs/[hash:8][ext][query]",
                        // },
                    },
                    // 处理字体图标配置
                    {
                        test: /\.(ttf|woff2?)$/,
                        type: "asset/resource",
                        // generator: {
                        //     filename: "static/media/[hash:8][ext][query]",
                        // },
                    },
                    // babel配置
                    {
                        test: /\.js$/,
                        // exclude: /node_modules/, // 排除node_modules代码不编译
                        include: path.resolve(__dirname, "../src"), // 也可以用包含
                        use: [
                            {
                                loader: "thread-loader", // 多进程打包
                                options: {
                                    workers: threads,  // 进程数量
                                },
                            },
                            {
                                loader: "babel-loader",
                                options: {
                                    // 智能预设也可写在这里
                                    // presets: ["@babel/preset-env"],
                                    cacheDirectory: true, // 开启babel编译缓存
                                    cacheCompression: false, // 缓存文件不要压缩
                                    plugins: ["@babel/plugin-transform-runtime"] // 减少代码体积
                                }
                            }
                        ]
                    },
                ]
            }
        ],
    },
    // 插件
    plugins: [
        // plugins的配置
        new ESLintWebpackPlugin({
            // eslint检测哪些文件
            context: path.resolve(__dirname, "../src"),
            exclude: "node_modules", // 默认值
            cache: true, // 开启缓存
            // 缓存目录
            cacheLocation: path.resolve(
                __dirname,
                "../node_modules/.cache/eslint-webpack-plugin/.eslintcache"
            ),
            threads, // 开启多进程
        }),
        new HtmlWebpackPlugin({
            // 以 public/index.html 为模板创建文件
            // 新的html文件有两个特点：1. 内容和源文件一致 2. 自动引入打包生成的js等资源
            template: path.resolve(__dirname, "../public/index.html"),
        }),
    ],
    // 开发服务器：不会输出资源，是在内存中编译打包的
    devServer: {
        host: "localhost", // 启动服务器域名
        port: "3000", // 启动服务器端口号
        open: true, // 是否自动打开浏览器
        // 在webpack5默认打开
        hot: true, // 开启HMR功能，热模块更新（只能用于开发环境，生产环境不需要了）
    },
    // 模式
    mode: "development",
    devtool: "cheap-module-source-map",
};